package com.sample.transaction.atomikos.db2.config;

import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.mysql.cj.jdbc.MysqlXADataSource;
import com.sample.transaction.atomikos.common.config.CustomerProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.sample.transaction.atomikos.db2",
	entityManagerFactoryRef = "secondEntityManagerFactory",
	transactionManagerRef = "secondTransactionManager")
public class SecondDbConfig {

    @Bean
    @ConfigurationProperties("db.second.datasource")
    public CustomerProperties secondDataSourceProperties() {
        return new CustomerProperties();
    }

    @Bean
    public DataSource secondDataSource() {
        CustomerProperties dataSourceProperties = secondDataSourceProperties();

        final MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl(dataSourceProperties.getUrl());
        mysqlXaDataSource.setPassword(dataSourceProperties.getPassword());
        mysqlXaDataSource.setUser(dataSourceProperties.getUsername());

        final AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("secondDataSource");
        xaDataSource.setPoolSize(5);
        xaDataSource.setMinPoolSize(5);
        xaDataSource.setMaxPoolSize(5);
        xaDataSource.setMaxIdleTime(dataSourceProperties.getMaxIdle());
        xaDataSource.setMaxLifetime(600000);
        xaDataSource.setConcurrentConnectionValidation(true);
        xaDataSource.setTestQuery("select 1 from dual");
        log.info("初始化第二数据库成功");
        return xaDataSource;
    }

//    @Bean
//    @ConfigurationProperties("db.second.datasource")
//    public DataSourceProperties secondDataSourceProperties() {
//        return new DataSourceProperties();
//    }
//
//    @Bean
//    public DataSource secondDataSource() {
//        return secondDataSourceProperties().initializeDataSourceBuilder().build();
//    }

    /**
     * 实体管理对象
     * @param builder  由spring注入这个对象，首先根据type注入（多个就取声明@Primary的对象），否则根据name注入
     * @return
     */
    @Bean
    public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(secondDataSource())
                .properties(getVendorProperties())
                .packages("com.sample.transaction.atomikos.db2.entity")
                .persistenceUnit("secondDb")
                .build();
    }

    /**
     * 事物管理对象
     * @param secondEntityManagerFactory 实体管理工厂对象（按照名称注入）
     * @return 平台事物管理器
     */
    @Bean(name = "secondTransactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("secondEntityManagerFactory") LocalContainerEntityManagerFactoryBean secondEntityManagerFactory){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(secondEntityManagerFactory.getObject());
        return transactionManager;
    }

    @Bean(name="jdbcTemplate2")
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(secondDataSource());
    }

    @Bean(name = "transactionTemplate2")
    public TransactionTemplate transactionTemplate(@Qualifier("secondTransactionManager")PlatformTransactionManager transactionManager){
        return new TransactionTemplate(transactionManager);
    }

    private Map<String, Object> getVendorProperties() {
        HashMap<String, Object> properties = new HashMap<>();
        // 注意这里要写为hibernate.hbm2ddl.auto 而不是hibernate.ddl-auto
        properties.put("hibernate.hbm2ddl.auto", "update");
        return properties;
    }

}
